package cn.virens.database.common;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cn.virens.exception.APIException;
import cn.virens.util.NumberUitl;
import cn.virens.util.page.Page;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

/**
 * 通用service实现类
 * 
 * @文件 :BaseServiceImpl.java
 * @作者 :cn.loioi
 * @创建时间 :2016年10月13日 下午1:24:27
 */
public abstract class BaseServiceImpl<T, M extends Mapper<T>> implements BaseService<T> {
	protected final Logger logger = LoggerFactory.getLogger(getClass());
	protected final M mBaseMapper;

	public BaseServiceImpl(M mBaseMapper) {
		this.mBaseMapper = mBaseMapper;
	}

	/**
	 * 插入一条数据
	 */
	@Override
	@Transactional(readOnly = false)
	public int insert(T record) throws APIException {
		if (record == null) return 0;
		// 插入addtime
		try {
			Method method = record.getClass().getMethod("setCreateTime", Date.class);
			if (method != null) {
				method.invoke(record, new Date());
			}
		} catch (Exception e) {
		}

		return mBaseMapper.insertSelective(record);
	}

	/**
	 * 更新一条数据
	 */
	@Override
	@Transactional(readOnly = false)
	public int update(T record) throws APIException {
		if (record == null) return 0;
		// 插入edittime
		try {
			Method method = record.getClass().getMethod("setUpdateTime", Date.class);
			if (method != null) {
				method.invoke(record, new Date());
			}
		} catch (Exception e) {
		}

		return mBaseMapper.updateByPrimaryKeySelective(record);
	}

	/**
	 * 删除一条数据
	 */
	@Override
	@Transactional(readOnly = false)
	public int delete(Object id) throws APIException {
		Object _id = getKey(id);

		if (_id == null) {
			return 0;
		} else {
			return mBaseMapper.deleteByPrimaryKey(_id);
		}
	}

	/**
	 * 查询全部数据
	 */
	@Override
	@Transactional(readOnly = true)
	public List<T> selectAll(Map<String, Object> param) throws APIException {
		return mBaseMapper.selectAll();
	}

	/**
	 * 根据ID查询一条数据
	 */
	@Override
	@Transactional(readOnly = true)
	public T selectOne(Object id) throws APIException {
		Object _id = getKey(id);

		if (_id == null) {
			return null;
		} else {
			return mBaseMapper.selectByPrimaryKey(getKey(id));
		}
	}

	@Override
	@Transactional(readOnly = true)
	public PageInfo<?> selectPage(Page page) throws APIException {
		// 分页查询
		if (!page.skip()) {
			// 获取分页参数
			int offset = page.getOffset();
			int pageSize = page.getPageSize();

			// 设置分页信息
			PageHelper.offsetPage(offset, pageSize, page.isCount()).setOrderBy(page.generateSort());
		}

		// 执行查询，并在查询之后清理分页信息
		try {
			return new PageInfo<>(doPageQuery(page.getParams()));
		} finally {
			PageHelper.clearPage();
		}
	}

	/**
	 * 默认查询全部，如需使用分页，并且有条件查询，复写该方法
	 * 
	 * @param param
	 * @return
	 * @throws APIException
	 */
	protected List<?> doPageQuery(Map<String, Object> param) throws APIException {
		return selectAll(param);
	}

	/**
	 * 获取形参
	 * 
	 * @return
	 */
	protected abstract Class<T> getGenericSuperclass();

	/**
	 * 获取主键值
	 * 
	 * @param id
	 * @return
	 */
	protected Object getKey(Object obj) {
		return NumberUitl.parseInt(obj, null);
	}

	public class ExampleWrapper extends Example {

		public ExampleWrapper() {
			super(getGenericSuperclass());
		}

		public ExampleWrapper(boolean exists, boolean notNull) {
			super(getGenericSuperclass(), exists, notNull);
		}

		public ExampleWrapper(boolean exists) {
			super(getGenericSuperclass(), exists);
		}

		public void createCriteria(CreateCriteriaInter inter) {
			inter.and(super.or());
		}
	}

	@FunctionalInterface
	protected interface CreateCriteriaInter {
		void and(Criteria criteria);
	}

}
